Next | Prev | Up | Top | Contents | Index

Example User DMA Function

The hypothetical function displayed in Example 4-2 is called to perform a series of DMA transfers from a specified device address. The code does not reflect any device initialization; all setup is presumably done by the caller. The code does not show the processing of the data, which is done in the hypothetical function processOneBuffer().

Example 4-2 : User-Level DMA Access to VME

/*
|| This function assumes that any device programming needed to
|| prepare the device for input has been done (using PIO) before
|| the function is called.  The bus number and device address
|| are function parameters.
*/

#define BLOCK_SIZE_TO_USE 4096
#include <udmalib.h>
#include <sys/vmereg.h>

extern void processOneBuffer(void *pBuffer);

int
readBlocks(int iBusNum, __uint32_t uiDevAddress)
{
    udmaid_t   *hEngine;    /* handle returned by dma_open */
    void       *pDMAbuffer; /* pointer from dma_allocbuf */
    vmeparms_t sParms;      /* operation parms for dma_mkparms */
    udmaprm_t  *hParms;     /* handle returned by dma_mkparms */
    int        iStartCode;  /* return code of dma_start */
/*
|| Open the DMA engine. Terminate if it won't open.
*/
    hEngine = dma_open(DMA_VMEBUS, iBusNum);
    if (!hEngine)
    {
        perror("dma_open");
        return(-1);
    }
/*
|| Allocate a special buffer for I/O. If that fails,
|| release the engine and terminate.
*/
    hDMAbuffer = dma_allocbuf(hEngine, BLOCK_SIZE_TO_USE);
    if (!hDMAbuffer)
    {
        perror("dma_allocbuf");
        dma_close(hEngine);
        return(-2);
    }
/*
|| Set up the VME parameters and "make" them.  A different set
|| of parameters is needed for each combination of vmeparms_t
|| values, buffer, and size.  This example uses only one set.
*/
    sParms.vp_block = 0;             /* this device does not do blocks */
    sParms.vp_datumsz = VME_DS_WORD; /* this is a 32-bit device */
    sParms.vp_dir = VME_READ;        /* input operation */
    sParms.vp_throt = VME_THROT_256; /* smaller burst size */
    sParms.vp_release = VME_REL_ROR; /* release on request */
    sParms.vp_addrmod = VME_A32NPAMOD; /* address modifier */
    hParms = dma_mkparms(hEngine, &sParms, pDMAbuffer, BLOCK_SIZE_TO_USE);
    if (!hParms)
    {
        perror("dma_mkparms");
        dma_freebuf(pDMAbuffer);
        dma_close(hEngine);
        return(-3);
    }
/*
|| Read and process blocks until error.
*/
    for(iStartCode=0;iStartCode==0;)
    {
         iStartCode = dms_start(hEngine, uiDevAddress, hParms);
         if (!iStartCode)
            processOneBuffer(pDMAbuffer);
    }
/*
|| Clean up and exit.
*/
    dma_freeparms(hEngine, hParms);
    dma_freebuf(pDMAbuffer);
    dma_close(hEngine);
    return 0;
}


Next | Prev | Up | Top | Contents | Index